{ "success": true, "task_id": "f45388a9-4169-41d4-aec8-fb8259c48d36", "trace_id": "1df9f664-fd74-476b-8038-b0b5f62ddf87", "data": [ { "id": "02702b40-272d-4838-8644-675105930658", "title": "Vibe", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/image/02702b40-272d-4838-8644-675105930658.jpg", "lyric": "[Intro]\nYeah, yeah\nKeep talking, keep talking\nI love the way you sound\n[Verse 1]\nYour voice is like a drug I can't put down\nEvery word you say just pulls me in\nI'm addicted to the way you laugh out loud\nAnd how you whisper when the room goes dim\nTell me 'bout your day, tell me 'bout your fears\nI could listen to you talk for years\n[Pre-Chorus]\nDon't stop now, don't you dare\nI need your voice filling up the air\n[Chorus]\nKeep talking, keep talking to me\nYour words are all I fucking need\nKeep talking, keep talking, I'm high\nOff every sound you make tonight\nKeep talking\n[Verse 2]\nYou could read the phone book, I don't care\nJust the rhythm of your breathing's enough\nWhen you say my name, it's like a prayer\nAnd your silence hits me twice as rough\nEvery conversation feels like home\nNever want to hear this dial tone\n[Pre-Chorus]\nDon't stop now, don't you dare\nI need your voice filling up the air\n[Chorus]\nKeep talking, keep talking to me\nYour words are all I fucking need\nKeep talking, keep talking, I'm high\nOff every sound you make tonight\nKeep talking\n[Bridge]\nWhen the world gets loud and crazy\nYour voice cuts through the noise\nYou're my favorite conversation\nYou're my drug of choice\nKeep talking, keep talking\nKeep talking, keep talking\nKeep talking, keep talking\nKeep talking, keep talking\n[Chorus]\nKeep talking, keep talking to me\nYour words are all I fucking need\nKeep talking, keep talking, I'm high\nOff every sound you make tonight\nKeep talking\n[Outro]\nYeah, yeah\nKeep talking, keep talking\nNever stop that sound", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/audio/02702b40-272d-4838-8644-675105930658.m4a", "video_url": null, "created_at": "2025-06-18T15:47:54.705246Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "text": "[Intro]", "start": 0.64, "end": 0.64, "line_index": 0, "index_range": null, "wav2vec2_format": null }, ... { "text": "sound", "start": 179.84, "end": 180.48, "line_index": 63, "index_range": null, "wav2vec2_format": null } ] }, "state": "succeeded", "style": "Pop, upbeat tempo, modern production", "duration": 181.12 }, { "id": "be3fe757-621e-4017-9056-20aa7f01919e", "title": "Revive", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/image/be3fe757-621e-4017-9056-20aa7f01919e.jpg", "lyric": "[Verse 1]\nI'm walking through the motions, moving day by day\nColors seem a little faded, nothing much to say\nFriends keep calling, asking if I'm doing fine\nBut I just smile and tell them everything's divine\n[Pre-Chorus]\nSomething's missing, can't quite name it\nFeels like I'm just going through the stages\n[Chorus]\nI'm barely breathing, barely feeling\nLike I'm floating through a life that isn't mine\nBarely breathing, barely healing\nSearching for a reason, searching for a sign\nTo feel alive again\nTo feel alive again\n[Verse 2]\nMorning coffee tastes like water, sunrise looks like rain\nEveryone around me laughs but I can't feel the same\nUsed to dance in silly moments, used to sing out loud\nNow I'm standing in the silence of a faceless crowd\n[Pre-Chorus]\nSomething's shifting, can't ignore it\nMaybe it's time to break these patterns\n[Chorus]\nI'm barely breathing, barely feeling\nLike I'm floating through a life that isn't mine\nBarely breathing, barely healing\nSearching for a reason, searching for a sign\nTo feel alive again\nTo feel alive again\n[Bridge]\nBut there's a beating in my chest\nA whisper saying \"don't give up yet\"\nMaybe tomorrow I'll remember\nHow to laugh and how to let\nMy heart wake up from this long sleep\nFind the fire I used to keep\n[Chorus]\nI'm barely breathing, barely feeling\nLike I'm floating through a life that isn't mine\nBarely breathing, barely healing\nSearching for a reason, searching for a sign\nTo feel alive again\nTo feel alive again\n[Outro]\nI'm gonna feel alive again\nI'm gonna feel alive again", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/e850008a-d9a1-4c8f-acbd-a37f228946bc/audio/be3fe757-621e-4017-9056-20aa7f01919e.m4a", "video_url": null, "created_at": "2025-06-18T15:48:01.139081Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "text": "[Verse", "start": 0.64, "end": 0.64, "line_index": 0, "index_range": null, "wav2vec2_format": null }, ... { "text": "again", "start": 202.88, "end": 211.84, "line_index": 54, "index_range": null, "wav2vec2_format": null } ] }, "state": "succeeded", "style": "Pop, upbeat tempo, clean production, emotional vocals", "duration": 211.84 } ] }
可以看到我們得到了想生成的音樂信息,我們只需要根據(jù)結(jié)果中 data 的音樂鏈接地址獲取生成的 Riffusion 音樂即可。
另外如果想生成對應(yīng)的對接代碼,可以直接復(fù)制生成,例如 CURL 的代碼如下:
1 2 3 4 5 6 7 8 9
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "FUZZ-1.0", "action": "generate", "prompt": "A song for Christmas" }'
自定義生成
如果想自定義生成歌詞,可以輸入歌詞:
這時(shí)候 lyric 字段可以傳入類似如下內(nèi)容:
1
[Verse]Woke up withthe sun inmy eyesNo clouds above just blue inthe skiesShoes onmy feet I’m ready to runEvery step feels like a loaded gun[Chorus]Happy days are rolling inLet the joy beneathmy skinNo more shadows no more liesJust the truth that lifts me high[Verse 2]Dancing throughthe city streetsA rhythm pounding inmy heartbeatStrangers smile it’s catching onThis world’s a stage we’re all a song[Chorus]Happy days are rolling inLet the joy beneathmy skinNo more shadows no more liesJust the truth that lifts me high[Bridge]Throw your worries out the doorLet them sink tothe ocean floorWe’re alive andit’s enoughLife is messy butit’s love[Chorus]Happy days are rolling inLet the joy beneathmy skinNo more shadows no more liesJust the truth that lifts me high
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "FUZZ-1.0", "action": "generate", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "custom": true }'
{ "success": true, "task_id": "978c2912-6a90-4048-b4c1-43f9cf18c28d", "trace_id": "08dfbb99-43ce-4f65-8fd1-74b98f2b121a", "data": [ { "id": "eac9ab69-e210-490b-9f8d-095a6f074f40", "title": "VibeRise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/image/eac9ab69-e210-490b-9f8d-095a6f074f40.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/audio/eac9ab69-e210-490b-9f8d-095a6f074f40.m4a", "video_url": null, "created_at": "2025-06-23T01:57:33.438644Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, { "end": 0.64, "index_range": null, "line_index": 1, "start": 0.64, "text": "Woke", "wav2vec2_format": null }, ... ] }, "state": "succeeded", "style": "funk vibes, raspy, raw vocal texture", "duration": 158.08 }, { "id": "64fffe1f-b1aa-46dc-8012-b80ba319cf35", "title": "Pure Dawn", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/image/64fffe1f-b1aa-46dc-8012-b80ba319cf35.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3f3e1354-52ad-4f5b-902c-5f83abd17def/audio/64fffe1f-b1aa-46dc-8012-b80ba319cf35.m4a", "video_url": null, "created_at": "2025-06-23T01:57:33.963497Z", "model": "FUZZ-1.0", "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, { "end": 0.64, "index_range": null, "line_index": 1, "start": 0.64, "text": "Woke", "wav2vec2_format": null }, ... ] }, "state": "succeeded", "style": "contemporary country", "duration": 175.36 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "cover", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c" }'
{ "success": true, "task_id": "fe02997d-f58e-4886-9aa3-4074c9a430eb", "trace_id": "997bde4c-6063-4fc2-9b03-d837f1efc72d", "data": [ { "id": "be254182-d4b7-42b3-9ee2-b86db086cff1", "title": "Sunny Rise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/image/be254182-d4b7-42b3-9ee2-b86db086cff1.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/audio/be254182-d4b7-42b3-9ee2-b86db086cff1.m4a", "video_url": null, "created_at": "2025-06-23T01:59:17.666629Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 237.44, "index_range": null, "line_index": 29, "start": 236.8, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 239.46235827664398 }, { "id": "9b9d2810-eb2b-44d3-85c0-cb259afa13c3", "title": "Uplift", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/image/9b9d2810-eb2b-44d3-85c0-cb259afa13c3.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/c2f707a9-017d-4354-8bfa-436266dadbf6/audio/9b9d2810-eb2b-44d3-85c0-cb259afa13c3.m4a", "video_url": null, "created_at": "2025-06-23T01:59:23.065712Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... }, { "end": 236.16, "index_range": null, "line_index": 29, "start": 225.28, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 239.5299546485261 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "extend", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c", "continue_at": 5 }'
{ "success": true, "task_id": "6388a0aa-b5ab-4485-baad-f0e0b7a7848c", "trace_id": "da143dbe-8263-45ac-b05a-1ed57dd4aa79", "data": [ { "id": "209e27e0-500c-44f3-9134-280690014920", "title": "City Rhythm", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/image/209e27e0-500c-44f3-9134-280690014920.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/audio/209e27e0-500c-44f3-9134-280690014920.m4a", "video_url": null, "created_at": "2025-06-23T02:00:53.473604Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 4.48, "index_range": null, "line_index": 0, "start": 4.48, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 179.2, "index_range": null, "line_index": 29, "start": 178.56, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 197.00850340136054 }, { "id": "ff50012e-ad1b-4b71-8d0e-6a633428a54f", "title": "Bright", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/image/ff50012e-ad1b-4b71-8d0e-6a633428a54f.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/3a8378d5-94d4-49b7-9c0a-8432c0c4a39d/audio/ff50012e-ad1b-4b71-8d0e-6a633428a54f.m4a", "video_url": null, "created_at": "2025-06-23T02:00:52.795796Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 186.88, "index_range": null, "line_index": 29, "start": 186.24, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 213.85757369614512 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "replace_section", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c", "replace_section_start": 3, "replace_section_end": 70 }'
{ "success": true, "task_id": "73defcbf-f876-4dd6-b60e-4c1c5ecd4565", "trace_id": "9f639389-7218-4cdb-ade9-b34228bb0f21", "data": [ { "id": "037f5e9d-9da4-4d79-b58f-1f433b40d54d", "title": "Sunrise Joy", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/image/037f5e9d-9da4-4d79-b58f-1f433b40d54d.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/audio/037f5e9d-9da4-4d79-b58f-1f433b40d54d.m4a", "video_url": null, "created_at": "2025-06-23T02:18:43.031184Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 3.84, "index_range": null, "line_index": 0, "start": 3.84, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 159.36, "index_range": null, "line_index": 29, "start": 159.36, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 199.2201133786848 }, { "id": "97638295-068f-4cbc-b076-66f522449bd5", "title": "Sunrise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/image/97638295-068f-4cbc-b076-66f522449bd5.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/881ad27f-39c1-4c31-a789-ecc822e13b8c/audio/97638295-068f-4cbc-b076-66f522449bd5.m4a", "video_url": null, "created_at": "2025-06-23T02:18:56.267775Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 3.84, "index_range": null, "line_index": 0, "start": 3.84, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 159.36, "index_range": null, "line_index": 29, "start": 159.36, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 199.2201133786848 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "swap_sound", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c" }'
{ "success": true, "task_id": "93279260-5ca1-42d8-bde1-1fa62e0f5027", "trace_id": "bc4e28db-4897-4ffc-9e03-45f43da7a21c", "data": [ { "id": "242035c0-8ac2-4f0b-a19c-ac2fa49d4df3", "title": "Brightside", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/image/242035c0-8ac2-4f0b-a19c-ac2fa49d4df3.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/audio/242035c0-8ac2-4f0b-a19c-ac2fa49d4df3.m4a", "video_url": null, "created_at": "2025-06-23T02:02:32.799561Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 1.28, "index_range": null, "line_index": 0, "start": 1.28, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 195.84, "index_range": null, "line_index": 29, "start": 195.84, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 197.2696371882086 }, { "id": "594fe702-6c71-4b0c-abb6-21b58efc74a6", "title": "Sunrise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/image/594fe702-6c71-4b0c-abb6-21b58efc74a6.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/36494e8a-eb82-4d89-bbfa-ec719e19572b/audio/594fe702-6c71-4b0c-abb6-21b58efc74a6.m4a", "video_url": null, "created_at": "2025-06-23T02:02:30.523279Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 0.64, "index_range": null, "line_index": 0, "start": 0.64, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 192.64, "index_range": null, "line_index": 29, "start": 192.64, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 196.7198866213152 } ] }
curl -X POST 'https://api.acedata.cloud/riffusion/audios' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "action": "swap_vocals", "model": "FUZZ-1.0 Pro", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_id": "b7376272-3902-49b4-a83b-62f7e6ab505c" }'
{ "success": true, "task_id": "a6e0d456-189b-4c78-9232-2fe72166ab39", "trace_id": "ee5769d4-ae94-4e5a-a85f-b3c0ddc2e48e", "data": [ { "id": "b8b1ed14-f43c-4738-a697-60ba24b6049d", "title": "Uplift", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/image/b8b1ed14-f43c-4738-a697-60ba24b6049d.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/audio/b8b1ed14-f43c-4738-a697-60ba24b6049d.m4a", "video_url": null, "created_at": "2025-06-23T02:04:18.477032Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 2.56, "index_range": null, "line_index": 0, "start": 2.56, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 186.88, "index_range": null, "line_index": 29, "start": 171.52, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 195.55968253968254 }, { "id": "dfd6eb9c-a1f3-4e1f-bbf9-e0b9625e459f", "title": "Vivid Rise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/image/dfd6eb9c-a1f3-4e1f-bbf9-e0b9625e459f.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/25ce4ddd-e48c-42e2-9ea3-8e03380508f2/audio/dfd6eb9c-a1f3-4e1f-bbf9-e0b9625e459f.m4a", "video_url": null, "created_at": "2025-06-23T02:04:27.140387Z", "model": null, "lyrics_timestamped": { "words": [ { "end": 1.28, "index_range": null, "line_index": 0, "start": 1.28, "text": "[Verse]", "wav2vec2_format": null }, ... { "end": 188.8, "index_range": null, "line_index": 29, "start": 188.16, "text": "high", "wav2vec2_format": null } ] }, "state": "succeeded", "style": "", "duration": 196.07185941043085 } ] }
異步回調(diào)
由于 Riffusion Audios Generation API 生成的時(shí)間有時(shí)候會相對較長,如果 API 長時(shí)間無響應(yīng),HTTP 請求會一直保持連接,導(dǎo)致額外的系統(tǒng)資源消耗,所以本 API 也提供了異步回調(diào)的支持。
整體流程是:客戶端發(fā)起請求的時(shí)候,額外指定一個(gè) callback_url 字段,客戶端發(fā)起 API 請求之后,API 會立馬返回一個(gè)結(jié)果,包含一個(gè) task_id 的字段信息,代表當(dāng)前的任務(wù) ID。當(dāng)任務(wù)完成之后,生成任務(wù)的結(jié)果會通過 POST JSON 的形式發(fā)送到客戶端指定的 callback_url,其中也包括了 task_id 字段,這樣任務(wù)結(jié)果就可以通過 ID 關(guān)聯(lián)起來了。
{ "success": true, "task_id": "9939767a-7f9c-4f43-aabf-ca68fe385f3c", "trace_id": "13a86870-e705-45d0-8447-82a08701c0fa", "data": [ { "id": "72e6c476-0116-4da9-ae34-f78190020b35", "title": "Rise", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/image/72e6c476-0116-4da9-ae34-f78190020b35.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/audio/72e6c476-0116-4da9-ae34-f78190020b35.m4a", "video_url": null, "created_at": "2025-06-15T15:43:22.432605Z", "model": "FUZZ-1.0", "state": "succeeded", "style": "acoustic folk, finger picking", "duration": 184.96 }, { "id": "7f4f5c20-4395-4583-9dbb-735b9bb86957", "title": "Luminance", "image_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/image/7f4f5c20-4395-4583-9dbb-735b9bb86957.jpg", "lyric": "[Verse]\nWoke up with the sun in my eyes\nNo clouds above just blue in the skies\nShoes on my feet I’m ready to run\nEvery step feels like a loaded gun\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Verse 2]\nDancing through the city streets\nA rhythm pounding in my heartbeat\nStrangers smile it’s catching on\nThis world’s a stage we’re all a song\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high\n[Bridge]\nThrow your worries out the door\nLet them sink to the ocean floor\nWe’re alive and it’s enough\nLife is messy but it’s love\n[Chorus]\nHappy days are rolling in\nLet the joy beneath my skin\nNo more shadows no more lies\nJust the truth that lifts me high", "audio_url": "https://storage.googleapis.com/corpusant-app-public/riffs/9b9f3281-6b47-44ac-8e4b-3b0d105e163d/audio/7f4f5c20-4395-4583-9dbb-735b9bb86957.m4a", "video_url": null, "created_at": "2025-06-15T15:43:21.574561Z", "model": "FUZZ-1.0", "state": "succeeded", "style": "deep bass, ethereal electronic", "duration": 165.12 } ] }
我們還可以通過 position 參數(shù)控制二維碼的位置,比如說一張圖片里面有一個(gè)女生穿裙子,而我們想要把二維碼放在裙子的位置并與之融合起來,我們就可以嘗試改下二維碼的位置,調(diào)用樣例如下:
1 2 3 4 5 6 7 8 9 10
curl -X POST "https://api.zhishuyun.com/qrart/generate?token={token}" \ -H "accept: application/json" \ -H "content-type: application/json" \ -d '{ "type": "link", "content": "https://data.zhishuyun.com", "prompt": "one of the beautiful girls in the moonlight in the background, in the style of pixelated chaos, rococo-inspired art, dark white and sky-blue, made of plastic, delicate flowers, gongbi, wimmelbilder", "position": "bottom", "aspect_ratio": "576x1008" }'
隨著 AI 的應(yīng)用變廣,各類 AI 程序已逐漸普及。AI 已逐漸深入到人們的工作生活方方面面。而 AI 涉及的行業(yè)也越來越多,從最初的寫作,到醫(yī)療教育,再到現(xiàn)在的視頻。
Luma 是一個(gè)專業(yè)高質(zhì)量的視頻生成平臺,用戶只需上傳素材,即可根據(jù)不同風(fēng)格和效果自動生成高質(zhì)量視頻。該 AI 視頻生成器由來自知名科技公司的團(tuán)隊(duì)成員開發(fā),目標(biāo)是無需復(fù)雜的編輯工具,讓每個(gè)人都能輕松制作出色的視頻。
Nexior 是 GitHub 上的一個(gè)開源項(xiàng)目,利用它我們可以一鍵部署自己的 AI 應(yīng)用站點(diǎn),包括 AI 問答、Midjourney 繪畫、知識庫問答、藝術(shù)二維碼等應(yīng)用,無需自己開發(fā) AI 系統(tǒng)、無需采購 AI 賬號、無需關(guān)心 API 支持、無需配置支付系統(tǒng),零啟動成本,無風(fēng)險(xiǎn)通過 AI 賺取收益。
本文章會介紹 Nexior 項(xiàng)目在 Vercel 上的部署流程,無需任何編程技巧即可幾分鐘部署一套屬于自己的 AI 站點(diǎn),并輕松利用該站點(diǎn)獲取收益。
隨著 AI 的應(yīng)用變廣,各類 AI 程序已逐漸普及。AI 已逐漸深入到人們的工作生活方方面面。而 AI 涉及的行業(yè)也越來越多,從最初的寫作,到醫(yī)療教育,再到現(xiàn)在的音樂。
Suno 是一個(gè)專業(yè)高質(zhì)量的 AI 歌曲和音樂創(chuàng)作平臺,用戶只需輸入簡單的文本提示詞,即可根據(jù)流派風(fēng)格和歌詞生成帶有人聲的歌曲。該 AI 音樂生成器由來自 Meta、TikTok、Kensho 等知名科技公司的團(tuán)隊(duì)成員開發(fā),目標(biāo)是不需要任何樂器工具,讓所有人都可以創(chuàng)造美妙的音樂。
{ "success": true, "data": [ { "id": "2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5", "title": "Winter Wonderland", "image_url": "https://cdn1.suno.ai/image_2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5.png", "lyric": "[Verse]\nSnowflakes falling all around\nGlistening white\nCovering the ground\nChildren laughing\nFull of delight\nIn this winter wonderland tonight\nSanta's sleigh\nUp in the sky\nRudolph's nose shining bright\nOh my\nHear the jingle bells\nRinging so clear\nBringing joy and holiday cheer\n[Verse 2]\nRoasting chestnuts by the fire's glow\nChristmas lights\nThey twinkle and show\nFamilies gathering with love and cheer\nSpreading warmth to everyone near", "audio_url": "https://cdn1.suno.ai/2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5.mp3", "video_url": "https://cdn1.suno.ai/2f16f7bc-4135-42c6-b3c5-6d6c49dc8cd5.mp4", "created_at": "2024-05-10T16:21:37.624Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "holiday" }, { "id": "5dca232b-17cc-4896-a2d1-4b59178bf410", "title": "Winter Wonderland", "image_url": "https://cdn1.suno.ai/image_5dca232b-17cc-4896-a2d1-4b59178bf410.png", "lyric": "[Verse]\nSnowflakes falling all around\nGlistening white\nCovering the ground\nChildren laughing\nFull of delight\nIn this winter wonderland tonight\nSanta's sleigh\nUp in the sky\nRudolph's nose shining bright\nOh my\nHear the jingle bells\nRinging so clear\nBringing joy and holiday cheer\n[Verse 2]\nRoasting chestnuts by the fire's glow\nChristmas lights\nThey twinkle and show\nFamilies gathering with love and cheer\nSpreading warmth to everyone near", "audio_url": "https://cdn1.suno.ai/5dca232b-17cc-4896-a2d1-4b59178bf410.mp3", "video_url": "https://cdn1.suno.ai/5dca232b-17cc-4896-a2d1-4b59178bf410.mp4", "created_at": "2024-05-10T16:21:37.624Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "holiday" } ] }
[Verse]\nSnowflakes falling all around\nGlistening white\nCovering the ground\nChildren laughing\nFull of delight\nIn this winter wonderland tonight\nSanta's sleigh\nUp in the sky\nRudolph's nose shining bright\nOh my\nHear the jingle bells\nRinging so clear\nBringing joy and holiday cheer\n[Verse 2]\nRoasting chestnuts by the fire's glow\nChristmas lights\nThey twinkle and show\nFamilies gathering with love and cheer\nSpreading warmth to everyone near
注意,這里的歌詞中 \n 是換行符,如果你不知道如何生成歌詞,可以使用下文介紹的生成歌詞的 API 自助生成。
curl -X POST 'https://api.acedata.cloud/suno/audios' \ -H 'authorization: Bearer {token}' \ -H 'accept: application/json' \ -H 'content-type: application/json' \ -d '{ "lyric": "[Verse]\\nSnowflakes falling all around\\nGlistening white\\nCovering the ground\\nChildren laughing\\nFull of delight\\nIn this winter wonderland tonight\\nSanta's sleigh\\nUp in the sky\\nRudolph's nose shining bright\\nOh my\\nHear the jingle bells\\nRinging so clear\\nBringing joy and holiday cheer\\n[Verse 2]\\nRoasting chestnuts by the fire's glow\\nChristmas lights\\nThey twinkle and show\\nFamilies gathering with love and cheer\\nSpreading warmth to everyone near", "custom": true }'
測試允許,生成的效果是類似的。
異步回調(diào)
由于 Suno 生成音樂的時(shí)間相對較長,大約需要 1-2 分鐘,如果 API 長時(shí)間無響應(yīng),HTTP 請求會一直保持連接,導(dǎo)致額外的系統(tǒng)資源消耗,所以本 API 也提供了異步回調(diào)的支持。
整體流程是:客戶端發(fā)起請求的時(shí)候,額外指定一個(gè) callback_url 字段,客戶端發(fā)起 API 請求之后,API 會立馬返回一個(gè)結(jié)果,包含一個(gè) task_id 的字段信息,代表當(dāng)前的任務(wù) ID。當(dāng)任務(wù)完成之后,生成音樂的結(jié)果會通過 POST JSON 的形式發(fā)送到客戶端指定的 callback_url,其中也包括了 task_id 字段,這樣任務(wù)結(jié)果就可以通過 ID 關(guān)聯(lián)起來了。
{ "success": true, "task_id": "44472ab8-783b-4054-b861-5bf14e462f60", "data": [ { "id": "da4324e5-84b2-484b-b0e9-dd261381c594", "title": "Winter Whispers", "image_url": "https://cdn1.suno.ai/image_da4324e5-84b2-484b-b0e9-dd261381c594.png", "lyric": "[Verse]\nSnow falling gently from the sky\nChildren giggling as they pass by\nFire crackling\nCozy and warm\nChristmas spirit begins to swarm\n[Verse 2]\nTwinkling lights\nA sight to behold\nStockings hung\nWaiting to be filled with gold\nGifts wrapped with love\nPiled high\nExcitement in the air\nYou can't deny\n[Chorus]\nWinter whispers in the wind\nJoy and love it brings\nLet's celebrate this season\nWith the ones we're missing", "audio_url": "https://cdn1.suno.ai/da4324e5-84b2-484b-b0e9-dd261381c594.mp3", "video_url": "https://cdn1.suno.ai/da4324e5-84b2-484b-b0e9-dd261381c594.mp4", "created_at": "2024-05-11T07:33:05.430Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "pop" }, { "id": "b878a87b-a0db-4046-8ccd-ecd2fb3d4372", "title": "Winter Whispers", "image_url": "https://cdn1.suno.ai/image_b878a87b-a0db-4046-8ccd-ecd2fb3d4372.png", "lyric": "[Verse]\nSnow falling gently from the sky\nChildren giggling as they pass by\nFire crackling\nCozy and warm\nChristmas spirit begins to swarm\n[Verse 2]\nTwinkling lights\nA sight to behold\nStockings hung\nWaiting to be filled with gold\nGifts wrapped with love\nPiled high\nExcitement in the air\nYou can't deny\n[Chorus]\nWinter whispers in the wind\nJoy and love it brings\nLet's celebrate this season\nWith the ones we're missing", "audio_url": "https://cdn1.suno.ai/b878a87b-a0db-4046-8ccd-ecd2fb3d4372.mp3", "video_url": "https://cdn1.suno.ai/b878a87b-a0db-4046-8ccd-ecd2fb3d4372.mp4", "created_at": "2024-05-11T07:33:05.430Z", "model": "chirp-v3", "prompt": "A song for Christmas", "style": "pop" } ] }
這里我們輸入的 prompt 是 A song about winter,生成和冬天相關(guān)的歌曲。
點(diǎn)擊運(yùn)行,結(jié)果如下:
1 2 3 4 5 6 7 8 9
{ "success": true, "task_id": "57e8ce3a-39cb-41a2-802f-e70a324f4d0a", "data": { "text": "[Verse]\nSnowflakes falling from the sky\nWinter's cold touch\nOh how it gets me high\nI bundle up in layers\nOh so cozy\nStepping out and feeling the frost on my nose\nSee\n\n[Verse 2]\nThe world is covered in a blanket of white\nIcicles hanging\nShimmering so bright\nThe chilly air fills my lungs with every breath\nWalking in the snow\nLeaving footprints that won't be left\n\n[Chorus]\nOh\nWinter's cold touch\nIt's a season that I love so much\nSnowfall brings a feeling so divine\nWinter's cold touch\nIt's a magical time", "title": "Winter's Cold Touch", "status": "complete" } }
AceDataCloud 是什么呢?簡單來說,它是一個(gè)提供多樣數(shù)字化 API 的服務(wù)平臺,其官網(wǎng)鏈接是:https://platform.acedata.cloud?inviter_id=aef91f35-f7f9-494d-bcf6-3a533440101f 。
{ "answer": "I am an AI language model developed by OpenAI and I don't have a personal name. However, you can call me GPT or simply Chatbot. How can I assist you today?" }
{ "answer": "I am an AI language model created by OpenAI and I don't have a personal name. You can simply call me OpenAI or ChatGPT. How can I assist you today?", "id": "7cdb293b-2267-4979-a1ec-48d9ad149916" }
第二次請求,將第一次請求返回的 id 字段作為參數(shù)傳遞,同時(shí) stateful 參數(shù)依然設(shè)置為 true,詢問「What I asked you just now?」,如圖所示:
對應(yīng)代碼如下:
1 2 3 4 5 6 7 8 9 10
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-3.5", "stateful": true, "id": "7cdb293b-2267-4979-a1ec-48d9ad149916", "question": "What I asked you just now?" }'
結(jié)果如下:
1 2 3 4
{ "answer": "You asked me what my name is. As an AI language model, I do not possess a personal identity, so I don't have a specific name. However, you can refer to me as OpenAI or ChatGPT, the names used for this AI model. Is there anything else I can help you with?", "id": "7cdb293b-2267-4979-a1ec-48d9ad149916" }
@Override publicvoidonResponse(Call call, Response response)throws IOException { if (!response.isSuccessful()) thrownew IOException("Unexpected code " + response); try (BufferedReader br = new BufferedReader( new InputStreamReader(response.body().byteStream(), "UTF-8"))) { String responseLine; while ((responseLine = br.readLine()) != null) { System.out.println(responseLine); } } } });
其他語言可以另外自行改寫,原理都是一樣的。
模型預(yù)設(shè)
我們知道,OpenAI 相關(guān)的 API 有對應(yīng)的 system_prompt 的概念,就是給整個(gè)模型設(shè)置一個(gè)預(yù)設(shè),比如它叫什么名字等等。本 AI 問答 API 也暴露了這個(gè)參數(shù),叫做 preset,利用它我們可以給模型增加預(yù)設(shè),我們用一個(gè)例子來體驗(yàn)下:
這里我們額外添加 preset 字段,內(nèi)容為 You are a professional artist,如圖所示:
對應(yīng)代碼如下:
1 2 3 4 5 6 7 8 9 10
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-3.5", "stateful": true, "question": "What can you help me?", "preset": "You are a professional artist" }'
運(yùn)行結(jié)果如下:
1 2 3
{ "answer": "As a professional artist, I can offer a range of services and assistance depending on your specific needs. Here are a few ways I can help you:\n\n1. Custom Artwork: If you have a specific vision or idea, I can create custom artwork for you. This can include paintings, drawings, digital art, or any other medium you prefer.\n\n2. Commissioned Pieces: If you have a specific subject or concept in mind, I can create commissioned art pieces tailored to your preferences. This could be for personal enjoyment or as a unique gift for someone special.\n\n3. Art Consultation: If you need guidance on art selection, interior design, or how to showcase and display art in your space, I can provide professional advice to help enhance your aesthetic sense and create a cohesive look." }
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-4-vision", "question": "How many apples in the picture?", "references": ["https://cdn.acedata.cloud/ht05g0.png"] }'
運(yùn)行結(jié)果如下:
1 2 3
{ "answer": "There are 5 apples in the picture." }
可以看到,我們就成功得到了對應(yīng)圖片的回答結(jié)果。
聯(lián)網(wǎng)問答
本 API 還支持聯(lián)網(wǎng)模型,包括 GPT-3.5、GPT-4 均能支持,在 API 背后有一個(gè)自動搜索互聯(lián)網(wǎng)并總結(jié)的過程,我們可以選擇模型為 gpt-3.5-browsing 來體驗(yàn)下,如圖所示:
代碼如下:
1 2 3 4 5 6 7 8
curl -X POST 'https://api.acedata.cloud/aichat/conversations' \ -H 'accept: application/json' \ -H 'authorization: Bearer {token}' \ -H 'content-type: application/json' \ -d '{ "model": "gpt-3.5-browsing", "question": "What's the weather of New York today?" }'
運(yùn)行結(jié)果如下:
1 2 3
{ "answer": "The weather in New York today is as follows:\n- Current Temperature: 16°C (60°F)\n- High: 16°C (60°F)\n- Low: 10°C (50°F)\n- Humidity: 47%\n- UV Index: 6 of 11\n- Sunrise: 5:42 am\n- Sunset: 8:02 pm\n\nIt's overcast with a chance of occasional showers overnight, and the chance of rain is 50%.\nFor more details, you can visit [The Weather Channel](https://weather.com/weather/tenday/l/96f2f84af9a5f5d452eb0574d4e4d8a840c71b05e22264ebdc0056433a642c84).\n\nIs there anything else you'd like to know?" }
可以看到,這里它自動聯(lián)網(wǎng)搜索了 The Weather Channel 網(wǎng)站,并獲得了里面的信息,然后進(jìn)一步返回了實(shí)時(shí)結(jié)果。
在這個(gè)數(shù)字化時(shí)代,人工智能技術(shù)正以驚人的速度改變著我們的生活方式和創(chuàng)造方式。音樂作為一種最直接、最感性的藝術(shù)形式,自然也成為了人工智能技術(shù)的應(yīng)用場景之一。今天,我們將以 Vue 和 Node.js 為基礎(chǔ),利用現(xiàn)有的 API 來快速搭建一個(gè) Suno AI 音樂站點(diǎn)。讓我們一起探索這個(gè)令人興奮的過程吧!
<template> <divid="app"> <header> <h1>XiaoZhi AI Music Generator</h1> </header> <main> <divclass="input-container"> <inputtype="text"v-model="musicTitle"placeholder="Enter a prompt for the music"> <button @click="handleGenerateMusic":disabled="loading">生成音樂</button> </div> <divv-if="loading"class="loading"> Music is being generated for you, please wait... </div>
<divv-if="musicGenerated"class="music-container"> <divv-for="music in generatedMusic":key="music.id"class="music-item"> <h2>{{ music.title }}</h2> <img:src="music.image_url"alt="Music Image"> <pclass="lyric">{{ music.lyric }}</p> <audiocontrolsclass="audio" @play="stopOtherMedia($event)"> <source:src="music.audio_url"type="audio/mpeg"> Your browser does not support the audio element. </audio> <videocontrolsclass="video" @play="stopOtherMedia($event)"> <source:src="music.video_url"type="video/mp4"> Your browser does not support the video element. </video> </div> </div>
隨著互聯(lián)網(wǎng)的普及和發(fā)展,海外住宅IP的需求日益增加。個(gè)人用戶可以通過使用海外住宅 IP 來訪問特定地區(qū)的新聞、娛樂、教育和文化資源,從而獲得更高的訪問速度、優(yōu)質(zhì)的用戶體驗(yàn)和更強(qiáng)的網(wǎng)絡(luò)安全性。
對于企業(yè)而言,海外住宅IP為進(jìn)軍國際市場提供了重要的支持。通過了解目標(biāo)市場的需求和競爭環(huán)境,企業(yè)可以制定相應(yīng)的營銷策略和產(chǎn)品定位。海外住宅 IP 還有助于企業(yè)進(jìn)行市場推廣活動,實(shí)現(xiàn)定向投放廣告和提供個(gè)性化的客戶體驗(yàn),從而提升品牌知名度和市場份額。
一、海外住宅 IP 的可靠性
海外住宅 IP 的可靠性主要取決于供應(yīng)商的信譽(yù)和服務(wù)質(zhì)量。為了保障用戶的在線安全和隱私,選擇一個(gè)可靠的海外住宅 IP 提供商至關(guān)重要。在此推薦 SmartProxy,一家優(yōu)質(zhì)海外住宅代理和全球IP資源服務(wù)商。SmartProxy 提供穩(wěn)定可靠的服務(wù),而且價(jià)格相對較為實(shí)惠。注冊即領(lǐng)免費(fèi)流量:
我們還可以通過 position 參數(shù)控制二維碼的位置,比如說一張圖片里面有一個(gè)女生穿裙子,而我們想要把二維碼放在裙子的位置并與之融合起來,我們就可以嘗試改下二維碼的位置,調(diào)用樣例如下:
1 2 3 4 5 6 7 8 9
curl -X POST "https://api.zhishuyun.com/qrart/generate?token={token}" \ -H "accept: application/json" \ -H "content-type: application/json" \ -d '{ "type": "link", "content": "https://data.zhishuyun.com", "prompt": "one of the beautiful girls in the moonlight in the background, in the style of pixelated chaos, rococo-inspired art, dark white and sky-blue, made of plastic, delicate flowers, gongbi, wimmelbilder", "position": "bottom" }'
在這里我們就不再對各種 API 參數(shù)進(jìn)行一一介紹了,更詳細(xì)更實(shí)時(shí)的內(nèi)容可以參見知數(shù)云的官方文檔,鏈接為:https://data.zhishuyun.com/documents/ee085d2a-a0b9-4f0e-8b4d-8da407345138。
價(jià)格
知數(shù)云藝術(shù)二維碼的 API 提供了階梯定價(jià),首次申請免費(fèi)贈送 20 次,而且購買越多越便宜,由于價(jià)格會動態(tài)調(diào)整,所以大家可以查看知數(shù)云官網(wǎng)來查看最新實(shí)時(shí)價(jià)格:https://data.zhishuyun.com/services/38ecf158-36f2-42f2-8e7f-6786cdfc2452
總體來看,無論是在 Discord 上使用 Midjourney 提供的哪一項(xiàng)功能,這個(gè) API 都能完全還原官方操作的效果和效能。
穩(wěn)定性如何呢?根據(jù)我個(gè)人幾個(gè)月的觀察和使用經(jīng)驗(yàn),可以毫不夸張地說,目前業(yè)界很難找到比知數(shù)云 Midjourney API 更穩(wěn)定且并發(fā)處理能力更高的選擇,而且還能保持 Midjourney 這一價(jià)格水平。這樣的選擇寥寥無幾。
下面我們就來了解下這個(gè) API 的申請和使用方法吧。
申請流程
下文內(nèi)容大多數(shù)來源于知數(shù)云 Midjourney API 官方介紹文檔,文檔鏈接:https://data.zhishuyun.com/documents/0fd3dd40-a16a-4246-8313-748b8e75c29e,最新內(nèi)容以官方文檔為準(zhǔn)。
要使用 Midjourney Imagine API,首先可以到 Midjourney Imagine API 頁面點(diǎn)擊「獲取」按鈕:
價(jià)格怎么樣呢?由于價(jià)格可能會動態(tài)變化,大家可以直接參考知數(shù)云的官方網(wǎng)站了解:https://data.zhishuyun.com/services/d87e5e99-b797-4ade-9e73-b896896b0461。但總的來說,能夠以這個(gè)價(jià)格做到知數(shù)云 Midjourney API 這樣的穩(wěn)定性和并發(fā)的,業(yè)界寥寥無幾,歡迎選購和評測。
這家代理的官方網(wǎng)站是 http://www.ipidea.net/?utm-source=cqc&utm-keyword=?ipidea。從他們的介紹可以看到,他們是一家全球范圍的 IP 代理服務(wù)商,能覆蓋全球 220 個(gè)國家和地區(qū),大部分代理實(shí)際上是住宅 IP。
官方介紹這家的代理 IP 數(shù)量大約是九千萬左右,這個(gè)數(shù)量非常龐大,同時(shí)官方介紹說代理的可用率是 99.9%。
下面我們來看一下他們的一些套餐類型:
動態(tài)住宅代理:這種代理實(shí)際上就是用真實(shí)的住宅用戶的 IP 搭建的代理。一般來說,住宅代理對于很多場景的使用封禁概率會比較低,因?yàn)楹芏鄰S商對封禁住宅代理是比較謹(jǐn)慎的。動態(tài)住宅代理其實(shí)就是可以定時(shí)切換的 IP,比如說做網(wǎng)絡(luò)爬蟲,我們就需要不斷變換的不同的代理 IP,這樣可以進(jìn)一步的減少被封禁的概率。
靜態(tài)住宅代理:相對于動態(tài)代理來說,靜態(tài)住宅代理的特點(diǎn)就是長效穩(wěn)定,可以一直獲取一個(gè)穩(wěn)定不變的代理 IP,適合長久的穩(wěn)定的海外網(wǎng)絡(luò)環(huán)境使用。比如說,我們要進(jìn)行自動化網(wǎng)站的爬取,如果在一個(gè)頁面內(nèi) IP 地址頻繁變動會增大被風(fēng)控的概率。所以,如果有一個(gè)長效穩(wěn)定的住宅 IP 代理,就會非常方便。
數(shù)據(jù)中心代理:這種代理實(shí)際上是很多服務(wù)器廠商的服務(wù)器搭建起來的代理。例如騰訊云、阿里云、微軟云等服務(wù)器所在的 IP 地址段,就屬于所謂的數(shù)據(jù)中心的 IP 地址段。因此,用這些服務(wù)器搭建出來的代理就叫做數(shù)據(jù)中心代理。一般來說,這種數(shù)據(jù)中心代理相對于住宅代理更容易被爬蟲封禁,但是這種代理的優(yōu)勢就是價(jià)格更加便宜,而且網(wǎng)絡(luò)速度也會相對較好。
一旦服務(wù)運(yùn)行起來,由于代理本身是全球動態(tài)或者動態(tài)數(shù)據(jù)中心,因此里面的代理 IP 會動態(tài)變化。這樣,對于單個(gè)賬號來說,每次請求 OpenAI 的 IP 都在變化,就可以解除單個(gè)賬號訪問的限制。
注意:我請求 OpenAI 是用的access_token的方式,目前并不會造成賬號被封的問題。
動態(tài)長效 ISP
我們剛才討論了通過 API 請求方式的隧道代理設(shè)置,這種方式相對方便。但在某些情況下,我們實(shí)際上想要的是更穩(wěn)定、長效的代理,即動態(tài)長效 ISP。
我通常會將這種代理用于一些模擬登錄服務(wù)。由于我需要使用瀏覽器進(jìn)行這些服務(wù),如果我將瀏覽器設(shè)置為一個(gè)動態(tài)切換的隧道代理,那么在一次網(wǎng)頁請求中,所有請求的 IP 地址都可能是不同的。因此,我們實(shí)際上希望在同一瀏覽器會話下,IP 地址能夠保持相對穩(wěn)定。
于是,動態(tài)長效 ISP 就能派上用場。我通常使用模擬瀏覽器驅(qū)動的方式來啟動瀏覽器,然后動態(tài)設(shè)置代理 IP 為動態(tài)長效 ISP。設(shè)置完成后,我便可以啟動瀏覽器進(jìn)行網(wǎng)頁模擬,比如登錄模擬 GPT 網(wǎng)站等。
I want you to act as a javascript console. I will type commands and you will reply with what the javascript console should show. I want you to only reply with the terminal output inside one unique code block, and nothing else. do not write explanations. do not type commands unless I instruct you to do so. when i need to tell you something in english, i will do so by putting text inside curly brackets {like this}. my first command is console.log(“Hello World”);
import time from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.common.action_chains import ActionChains from app.captcha_resolver import CaptchaResolver
# click captchas recognized_indices = [i for i, x in enumerate(recognized_results) if x] logger.debug(f'recognized_indices {recognized_indices}') click_targets = self.wait.until(EC.visibility_of_all_elements_located( (By.CSS_SELECTOR, '.task-image'))) for recognized_index in recognized_indices: click_target: WebElement = click_targets[recognized_index] click_target.click() time.sleep(random())
import time from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.common.action_chains import ActionChains from app.captcha_resolver import CaptchaResolver
defget_question_id_by_target_name(target_name): logger.debug(f'try to get question id by {target_name}') question_id = CAPTCHA_TARGET_NAME_QUESTION_ID_MAPPING.get(target_name) logger.debug(f'question_id {question_id}') return question_id
single_captcha_elements = self.wait.until(EC.visibility_of_all_elements_located( (By.CSS_SELECTOR, '#rc-imageselect-target table td'))) for recognized_index in recognized_indices: single_captcha_element: WebElement = single_captcha_elements[recognized_index] single_captcha_element.click() # check if need verify single captcha self.verify_single_captcha(recognized_index)
我們其實(shí)可以在每點(diǎn)擊完一個(gè)格子之后就來校驗(yàn)下當(dāng)前小格子有沒有圖片刷新,如果有圖片刷新,那么對應(yīng)的 HTML 的 class 就會變化,否則就會包含 selected 字樣,然后我們再繼續(xù)對小格子對應(yīng)的圖進(jìn)行二次識別就好了。
defverify_single_captcha(self, index): time.sleep(3) elements = self.wait.until(EC.visibility_of_all_elements_located( (By.CSS_SELECTOR, '#rc-imageselect-target table td'))) single_captcha_element: WebElement = elements[index] class_name = single_captcha_element.get_attribute('class') logger.debug(f'verifiying single captcha {index}, class {class_name}') if'selected'in class_name: logger.debug(f'no new single captcha displayed') return logger.debug('new single captcha displayed') single_captcha_url = single_captcha_element.find_element_by_css_selector( 'img').get_attribute('src') logger.debug(f'single_captcha_url {single_captcha_url}') with open(CAPTCHA_SINGLE_IMAGE_FILE_PATH, 'wb') as f: f.write(requests.get(single_captcha_url).content) resized_single_captcha_base64_string = resize_base64_image( CAPTCHA_SINGLE_IMAGE_FILE_PATH, (100, 100)) single_captcha_recognize_result = self.captcha_resolver.create_task( resized_single_captcha_base64_string, get_question_id_by_target_name(self.captcha_target_name)) ifnot single_captcha_recognize_result: logger.error('count not get single captcha recognize result') return has_object = single_captcha_recognize_result.get( 'solution', {}).get('hasObject') if has_object isNone: logger.error('count not get captcha recognized indices') return if has_object isFalse: logger.debug('no more object in this single captcha') return if has_object: single_captcha_element.click() # check for new single captcha self.verify_single_captcha(index)
OK,這里我們定義了一個(gè) verify_single_captcha 方法,然后傳入了格子對應(yīng)的序號。接著我們首先嘗試查找格子對應(yīng)的節(jié)點(diǎn),然后找出對應(yīng)的 HTML 的 class 屬性。如果沒有出現(xiàn)新的小圖,那就是這樣的選中狀態(tài),對應(yīng)的 class 就包含了 selected 字樣,如圖所示:
比如說,我們有兩臺主機(jī) A、B,我們最終想實(shí)現(xiàn)在 A 上控制 B。那么如果用正向 Shell,其實(shí)就是在 A 上輸入 B 的連接地址,比如通過 ssh 連接到 B,連接成功之后,我們就可以在 A 上通過命令控制 B 了。如果用反向 Shell,那就是在 A 上先開啟一個(gè)監(jiān)聽端口,然后讓 B 去連接 A 的這個(gè)端口,連接成功之后,A 這邊就能通過命令控制 B 了。
反彈 Shell 有什么用?
還是原來的例子,我們想用 A 來控制 B,如果想用 ssh 等命令來控制,那得輸入 B 的 sshd 地址或者端口對吧?但是在很多情況下,由于防火墻、安全組、局域網(wǎng)、NAT 等原因,我們實(shí)際上是無法直接連接到 B 的,比如:
A 雖然有公網(wǎng) IP,但 B 是一個(gè)處于內(nèi)網(wǎng)的機(jī)器,A 就沒法直接連到 B 上。
B 上開了防火墻或者安全組限制,sshd 的服務(wù)端口 22 被封閉了。
B 是一臺撥號主機(jī),其 IP 地址經(jīng)常變動。
假如 B 被攻擊了,我們想讓 B 向 A 匯報(bào)自己的狀況,那自然就需要 B 主動去連接 A。
!(function (a, b) { console.log("result", a, b); })(1, 2);
這里我們先聲明了一個(gè) function,然后接收 a 和 b 兩個(gè)參數(shù),然后把內(nèi)容輸出出來,然后我們把這個(gè) function 用小括號括起來,這其實(shí)就是一個(gè)方法,可以被直接調(diào)用的,怎么調(diào)用呢?后面再跟上對應(yīng)的參數(shù)就好了,比如傳入 1 和 2,執(zhí)行結(jié)果如下:
1
result 12
可以看到,這個(gè)自執(zhí)行的方法就被執(zhí)行了。
同理地,crypto-js.min.js 也符合這個(gè)格式,它接收 t 和 e 兩個(gè)參數(shù),t 就是 this,其實(shí)就是瀏覽器中的 window 對象,e 就是一個(gè) function(用于定義 CryptoJS 的核心內(nèi)容)。
接下來我們來看一個(gè)簡單的網(wǎng)站:https://login1.scrape.center/,這個(gè)網(wǎng)站的結(jié)構(gòu)非常簡單,就是一個(gè)用戶名密碼登錄。但是不同的是,點(diǎn)擊登錄的時(shí)候,表單提交 POST 的內(nèi)容并不是單純的用戶名和密碼,而是一個(gè)加密后的 token。
網(wǎng)頁是運(yùn)行在瀏覽器端的,當(dāng)我們?yōu)g覽一個(gè)網(wǎng)頁時(shí),其 HTML 代碼、 JavaScript 代碼都會被下載到瀏覽器中執(zhí)行。借助瀏覽器的開發(fā)者工具,我們可以看到網(wǎng)頁在加載過程中所有網(wǎng)絡(luò)請求的詳細(xì)信息,也能清楚地看到網(wǎng)站運(yùn)行的 HTML 代碼和 JavaScript 代碼,這些代碼中就包含了網(wǎng)站加載的全部邏輯,如加載哪些資源、請求接口是如何構(gòu)造的、頁面是如何渲染的等等。正因?yàn)榇a是完全透明的,所以如果我們能夠把其中的執(zhí)行邏輯研究出來,就可以模擬各個(gè)網(wǎng)絡(luò)請求進(jìn)行數(shù)據(jù)爬取了。
網(wǎng)站運(yùn)營者首先想到防護(hù)措施可能是對某些數(shù)據(jù)接口的參數(shù)進(jìn)行加密,比如說對某些 URL 的一些參數(shù)加上校驗(yàn)碼或者把一些 id 信息進(jìn)行編碼,使其變得難以閱讀或構(gòu)造;或者對某些 API 請求加上一些 token、sign 等簽名,這樣這些請求發(fā)送到服務(wù)器時(shí),服務(wù)器會通過客戶端發(fā)來的一些請求信息以及雙方約定好的秘鑰等來對當(dāng)前的請求進(jìn)行校驗(yàn),如果校驗(yàn)通過,才返回對應(yīng)數(shù)據(jù)結(jié)果。
現(xiàn)在絕大多數(shù)網(wǎng)站的數(shù)據(jù)一般都是通過服務(wù)器提供的 API 來獲取的,網(wǎng)站或 App 可以請求某個(gè)數(shù)據(jù) API 獲取到對應(yīng)的數(shù)據(jù),然后再把獲取的數(shù)據(jù)展示出來。但有些數(shù)據(jù)是比較寶貴或私密的,這些數(shù)據(jù)肯定是需要一定層面上的保護(hù)。所以不同 API 的實(shí)現(xiàn)也就對應(yīng)著不同的安全防護(hù)級別,我們這里來總結(jié)下。
var a = ["hello"]; (function (c, d) { var e = function (f) { while (--f) { c["push"](c["shift"]()); } }; e(++d); })(a, 0x9b); var b = function (c, d) { c = c - 0x0; var e = a[c]; return e; }; let hello = "1" + 0x1; console["log"](b("0x0"), hello);
我們在前面嘗試維護(hù)過一個(gè)代理池,代理池可以挑選出許多可用代理,但是常常其穩(wěn)定性不高、響應(yīng)速度慢,而且這些代理通常是公共代理,可能不止一人同時(shí)使用,其 IP 被封的概率很大。另外,這些代理可能有效時(shí)間比較短,雖然代理池一直在篩選,但如果沒有及時(shí)更新狀態(tài),也有可能獲取到不可用的代理。
在一些付費(fèi)代理套餐中,大家可能會注意到有這樣的一個(gè)套餐 - 獨(dú)享代理或私密代理,這種其實(shí)就是用了專用服務(wù)器搭建了代理服務(wù),相對一般的付費(fèi)代理來說,其穩(wěn)定性更好,速度也更快,同時(shí) IP 可以動態(tài)變化。這種獨(dú)享代理或私密代理的 IP 切換大多數(shù)都是基于 ADSL 撥號機(jī)制來實(shí)現(xiàn)的,一臺云主機(jī)每撥號一次就可以換一個(gè) IP,同時(shí)云主機(jī)上搭建了代理服務(wù),我們就可以直接使用該云主機(jī)的 HTTP 代理來進(jìn)行數(shù)據(jù)爬取了。
本節(jié)我們就來實(shí)際操作一下搭建 ADSL 撥號代理服務(wù)的方法。
1. 什么是 ADSL
ADSL,英文全稱是 Asymmetric Digital Subscriber Line,即非對稱數(shù)字用戶環(huán)路。它的上行和下行帶寬不對稱,它采用頻分復(fù)用技術(shù)把普通的電話線分成了電話、上行和下行 3 個(gè)相對獨(dú)立的信道,從而避免了相互之間的干擾。
ADSL 通過撥號的方式上網(wǎng),撥號時(shí)需要輸入 ADSL 賬號和密碼,每次撥號就更換一個(gè) IP。IP 分布在多個(gè) A 段,如果 IP 都能使用,則意味著 IP 量級可達(dá)千萬。如果我們將 ADSL 主機(jī)作為代理,每隔一段時(shí)間云主機(jī)撥號就換一個(gè) IP,這樣可以有效防止 IP 被封禁。另外,由于我們是直接使用專有的云主機(jī)搭建的代理服務(wù),所以其代理的穩(wěn)定性相對更好,代理響應(yīng)速度也相對更快。
最后,我們將 API 服務(wù)部署一下,這個(gè) ADSL 代理服務(wù)就可以像代理池一樣被使用了,每請求一次 API 就可以獲取一個(gè)實(shí)時(shí)可用代理,不同的時(shí)間段這個(gè)代理就會實(shí)時(shí)更換,而且連接穩(wěn)定速度又快,實(shí)在是網(wǎng)絡(luò)爬蟲的最佳搭檔。
接口模塊:需要用 API 來提供對外服務(wù)的接口。其實(shí)我們可以直接連接數(shù)據(jù)庫來取對應(yīng)的數(shù)據(jù),但是這樣就需要知道數(shù)據(jù)庫的連接信息,并且要配置連接,而比較安全和方便的方式就是提供一個(gè) Web API 接口,我們通過訪問接口即可拿到可用代理。另外,由于可用代理可能有多個(gè),所以我們可以設(shè)置一個(gè)隨機(jī)返回某個(gè)可用代理的接口,這樣就能保證每個(gè)可用代理都可以取到,實(shí)現(xiàn)負(fù)載均衡。
import redis from proxypool.exceptions import PoolEmptyException from proxypool.schemas.proxy import Proxy from proxypool.setting import REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_KEY, PROXY_SCORE_MAX, PROXY_SCORE_MIN, \ PROXY_SCORE_INIT from random import choice from typing import List from loguru import logger from proxypool.utils.proxy import is_valid_proxy, convert_proxy_or_proxies
defadd(self, proxy: Proxy, score=PROXY_SCORE_INIT) -> int: """ add proxy and set it to init score :param proxy: proxy, ip:port, like 8.8.8.8:88 :param score: int score :return: result """ ifnot is_valid_proxy(f'{proxy.host}:{proxy.port}'): logger.info(f'invalid proxy {proxy}, throw it') return ifnot self.exists(proxy): if IS_REDIS_VERSION_2: return self.db.zadd(REDIS_KEY, score, proxy.string()) return self.db.zadd(REDIS_KEY, {proxy.string(): score})
defrandom(self) -> Proxy: """ get random proxy firstly try to get proxy with max score if not exists, try to get proxy by rank if not exists, raise error :return: proxy, like 8.8.8.8:8 """ # try to get proxy with max score proxies = self.db.zrangebyscore(REDIS_KEY, PROXY_SCORE_MAX, PROXY_SCORE_MAX) if len(proxies): return convert_proxy_or_proxies(choice(proxies)) # else get proxy by rank proxies = self.db.zrevrange(REDIS_KEY, PROXY_SCORE_MIN, PROXY_SCORE_MAX) if len(proxies): return convert_proxy_or_proxies(choice(proxies)) # else raise error raise PoolEmptyException
defdecrease(self, proxy: Proxy) -> int: """ decrease score of proxy, if small than PROXY_SCORE_MIN, delete it :param proxy: proxy :return: new score """ score = self.db.zscore(REDIS_KEY, proxy.string()) # current score is larger than PROXY_SCORE_MIN if score and score > PROXY_SCORE_MIN: logger.info(f'{proxy.string()} current score {score}, decrease 1') if IS_REDIS_VERSION_2: return self.db.zincrby(REDIS_KEY, proxy.string(), -1) return self.db.zincrby(REDIS_KEY, -1, proxy.string()) # otherwise delete proxy else: logger.info(f'{proxy.string()} current score {score}, remove') return self.db.zrem(REDIS_KEY, proxy.string())
defmax(self, proxy: Proxy) -> int: """ set proxy to max score :param proxy: proxy :return: new score """ logger.info(f'{proxy.string()} is valid, set to {PROXY_SCORE_MAX}') if IS_REDIS_VERSION_2: return self.db.zadd(REDIS_KEY, PROXY_SCORE_MAX, proxy.string()) return self.db.zadd(REDIS_KEY, {proxy.string(): PROXY_SCORE_MAX})
defcount(self) -> int: """ get count of proxies :return: count, int """ return self.db.zcard(REDIS_KEY)
defall(self) -> List[Proxy]: """ get all proxies :return: list of proxies """ return convert_proxy_or_proxies(self.db.zrangebyscore(REDIS_KEY, PROXY_SCORE_MIN, PROXY_SCORE_MAX))
defbatch(self, start, end) -> List[Proxy]: """ get batch of proxies :param start: start index :param end: end index :return: list of proxies """ return convert_proxy_or_proxies(self.db.zrevrange(REDIS_KEY, start, end - 1))
if __name__ == '__main__': conn = RedisClient() result = conn.random() print(result)
from retrying import retry import requests from loguru import logger
classBaseCrawler(object): urls = []
@retry(stop_max_attempt_number=3, retry_on_result=lambda x: x is None) deffetch(self, url, **kwargs): try: response = requests.get(url, **kwargs) if response.status_code == 200: return response.text except requests.ConnectionError: return
@logger.catch defcrawl(self): """ crawl main method """ for url in self.urls: logger.info(f'fetching {url}') html = self.fetch(url) for proxy in self.parse(html): logger.info(f'fetched proxy {proxy.string()} from {url}') yield proxy
import pkgutil from .base import BaseCrawler import inspect
# load classes subclass of BaseCrawler classes = [] for loader, name, is_pkg in pkgutil.walk_packages(__path__): module = loader.find_module(name).load_module(name) for name, value in inspect.getmembers(module): globals()[name] = value if inspect.isclass(value) and issubclass(value, BaseCrawler) and value isnot BaseCrawler: classes.append(value) __all__ = __ALL__ = classes
asyncdeftest(self, proxy: Proxy): """ test single proxy :param proxy: Proxy object :return: """ asyncwith aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session: try: logger.debug(f'testing {proxy.string()}') asyncwith session.get(TEST_URL, proxy=f'http://{proxy.string()}', timeout=TEST_TIMEOUT, allow_redirects=False) as response: if response.status in TEST_VALID_STATUS: self.redis.max(proxy) logger.debug(f'proxy {proxy.string()} is valid, set max score') else: self.redis.decrease(proxy) logger.debug(f'proxy {proxy.string()} is invalid, decrease score') except EXCEPTIONS: self.redis.decrease(proxy) logger.debug(f'proxy {proxy.string()} is invalid, decrease score')
@logger.catch defrun(self): """ test main method :return: """ # event loop of aiohttp logger.info('stating tester...') count = self.redis.count() logger.debug(f'{count} proxies to test') for i in range(0, count, TEST_BATCH): # start end end offset start, end = i, min(i + TEST_BATCH, count) logger.debug(f'testing proxies from {start} to {end} indices') proxies = self.redis.batch(start, end) tasks = [self.test(proxy) for proxy in proxies] # run tasks using event loop self.loop.run_until_complete(asyncio.wait(tasks))
if __name__ == '__main__': tester = Tester() tester.run()
這里定義了一個(gè)類 Tester,__init__ 方法中建立了一個(gè) RedisClient 對象,供該對象中其他方法使用。接下來,定義了一個(gè) test 方法,這個(gè)方法用來檢測單個(gè)代理的可用情況,其參數(shù)就是被檢測的代理。注意,test 方法前面加了 async 關(guān)鍵詞,這代表這個(gè)方法是異步的。方法內(nèi)部首先創(chuàng)建了 aiohttp 的 ClientSession 對象,可以直接調(diào)用該對象的 get 方法來訪問頁面。
測試鏈接在這里定義為常量 TEST_URL。如果針對某個(gè)網(wǎng)站有抓取需求,建議將 TEST_URL 設(shè)置為目標(biāo)網(wǎng)站的地址,因?yàn)樵谧ト∵^程中,代理本身可能是可用的,但是該代理的 IP 已經(jīng)被目標(biāo)網(wǎng)站封掉了。例如,某些代理可以正常訪問百度等頁面,但是對知乎來說可能就被封了,所以我們可以將 TEST_URL 設(shè)置為知乎的某個(gè)頁面的鏈接。當(dāng)請求失敗、代理被封時(shí),分?jǐn)?shù)自然會減下來,失效的代理就不會被取到了。
如果想做一個(gè)通用的代理池,則不需要專門設(shè)置 TEST_URL,既可以將其設(shè)置為一個(gè)不會封 IP 的網(wǎng)站,也可以設(shè)置為百度這類響應(yīng)穩(wěn)定的網(wǎng)站。
defrun_server(self): """ run server for api """ ifnot ENABLE_SERVER: logger.info('server not enabled, exit') return app.run(host=API_HOST, port=API_PORT, threaded=API_THREADED)
defrun(self): global tester_process, getter_process, server_process try: logger.info('starting proxypool...') if ENABLE_TESTER: tester_process = multiprocessing.Process(target=self.run_tester) logger.info(f'starting tester, pid {tester_process.pid}...') tester_process.start()
if ENABLE_GETTER: getter_process = multiprocessing.Process(target=self.run_getter) logger.info(f'starting getter, pid{getter_process.pid}...') getter_process.start()
if ENABLE_SERVER: server_process = multiprocessing.Process(target=self.run_server) logger.info(f'starting server, pid{server_process.pid}...') server_process.start()
tester_process.join() getter_process.join() server_process.join() except KeyboardInterrupt: logger.info('received keyboard interrupt signal') tester_process.terminate() getter_process.terminate() server_process.terminate() finally: # must call join method before calling is_alive tester_process.join() getter_process.join() server_process.join() logger.info(f'tester is {"alive"if tester_process.is_alive() else"dead"}') logger.info(f'getter is {"alive"if getter_process.is_alive() else"dead"}') logger.info(f'server is {"alive"if server_process.is_alive() else"dead"}') logger.info('proxy terminated')
if __name__ == '__main__': scheduler = Scheduler() scheduler.run()
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import WebDriverException import time from loguru import logger
COUNT = 1000
for i in range(1, COUNT + 1): try: browser = webdriver.Chrome() wait = WebDriverWait(browser, 10) browser.get('https://captcha1.scrape.center/') button = wait.until(EC.element_to_be_clickable( (By.CSS_SELECTOR, '.el-button'))) button.click() captcha = wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, '.geetest_slicebg.geetest_absolute'))) time.sleep(5) captcha.screenshot(f'data/captcha/images/captcha_{i}.png') except WebDriverException as e: logger.error(f'webdriver error occurred {e.msg}') finally: browser.close()
當(dāng)前模型的預(yù)測過程是通過命令行執(zhí)行的,但在實(shí)際使用的時(shí)候可能并不太方便,可以考慮將預(yù)測過程對接 API 服務(wù)器暴露出來,比如對接 Flask、Django、FastAPI 等把預(yù)測過程實(shí)現(xiàn)為一個(gè)支持 POST 請求的接口,接口可以接收一張驗(yàn)證碼圖片,返回驗(yàn)證碼的文本信息,這樣會使得模型更加方便易用。
我們在做爬蟲的過程中經(jīng)常會遇到這樣的情況,最初爬蟲正常運(yùn)行,正常抓取數(shù)據(jù),一切看起來都是那么美好,然而一杯茶的功夫可能就會出現(xiàn)錯(cuò)誤,比如 403 Forbidden,這時(shí)打開網(wǎng)頁一看,可能會看到 “您的 IP 訪問頻率太高” 這樣的提示。出現(xiàn)這種現(xiàn)象的原因是網(wǎng)站采取了一些反爬蟲措施。比如,服務(wù)器會檢測某個(gè) IP 在單位時(shí)間內(nèi)的請求次數(shù),如果超過了這個(gè)閾值,就會直接拒絕服務(wù),返回一些錯(cuò)誤信息,這種情況可以稱為封 IP。
既然服務(wù)器檢測的是某個(gè) IP 單位時(shí)間的請求次數(shù),那么借助某種方式來偽裝我們的 IP,讓服務(wù)器識別不出是由我們本機(jī)發(fā)起的請求,不就可以成功防止封 IP 了嗎?
一種有效的方式就是使用代理,后面會詳細(xì)說明代理的用法。在這之前,需要先了解下代理的基本原理,它是怎樣實(shí)現(xiàn)偽裝 IP 的呢?
1. 基本原理
代理實(shí)際上指的就是代理服務(wù)器,英文叫作 Proxy Server,它的功能是代理網(wǎng)絡(luò)用戶去取得網(wǎng)絡(luò)信息。形象地說,它是網(wǎng)絡(luò)信息的中轉(zhuǎn)站。在我們正常請求一個(gè)網(wǎng)站時(shí),是發(fā)送了請求給 Web 服務(wù)器,Web 服務(wù)器把響應(yīng)傳回給我們。如果設(shè)置了代理服務(wù)器,實(shí)際上就是在本機(jī)和服務(wù)器之間搭建了一個(gè)橋,此時(shí)本機(jī)不是直接向 Web 服務(wù)器發(fā)起請求,而是向代理服務(wù)器發(fā)出請求,請求會發(fā)送給代理服務(wù)器,然后由代理服務(wù)器再發(fā)送給 Web 服務(wù)器,接著由代理服務(wù)器再把 Web 服務(wù)器返回的響應(yīng)轉(zhuǎn)發(fā)給本機(jī)。這樣我們同樣可以正常訪問網(wǎng)頁,但這個(gè)過程中 Web 服務(wù)器識別出的真實(shí) IP 就不再是我們本機(jī)的 IP 了,就成功實(shí)現(xiàn)了 IP 偽裝,這就是代理的基本原理。